package com.dragon.modules.yuegou.service.impl.marketing;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.entity.marketing.ActivityEntity;
import com.dragon.modules.yuegou.entity.marketing.ActivitySpuRefEntity;
import com.dragon.modules.yuegou.entity.product.SkuEntity;
import com.dragon.modules.yuegou.enums.code.BusinessCode;
import com.dragon.modules.yuegou.enums.code.DistrictCode;
import com.dragon.modules.yuegou.enums.code.MarketingCode;
import com.dragon.modules.yuegou.enums.code.MerchantCode;
import com.dragon.modules.yuegou.enums.marketing.ActivityStatus;
import com.dragon.modules.yuegou.mapper.marketing.ActivityMapper;
import com.dragon.modules.yuegou.model.marketing.Activity;
import com.dragon.modules.yuegou.model.marketing.ActivitySpuRef;
import com.dragon.modules.yuegou.query.marketing.ActivityQuery;
import com.dragon.modules.yuegou.query.marketing.ActivitySpuRefQuery;
import com.dragon.modules.yuegou.service.marketing.ActivityService;
import com.dragon.modules.yuegou.service.marketing.ActivitySpuRefService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.utils.PageToResultUtils;
import com.dragon.modules.yuegou.web.Check;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 抽奖活动表 服务实现
 *
 * @author pbuilder generated
 * @date 2019-04-23 14:12:34
 * @version 2.0
 */
@Slf4j
@Service("mktActivityService")
public class ActivityServiceImpl
		extends ServiceImpl<ActivityMapper, ActivityEntity>
		implements ActivityService {

	@Autowired
	private ActivitySpuRefService activitySpuRefService;

	@Autowired
	private SkuService skuService;

	@Override
	public IPage<Activity> search(PageRequest page, ActivityQuery query){
		Check.notNull(query.getBusdId(), DistrictCode.DISTRICT_NOTNULL.getMessage());
		QueryWrapper<ActivityEntity> wrapper = query.toQueryWrapper();
		wrapper.orderByDesc(Activity.COL_CREATED_TIME);
		IPage<Activity> iPage = page(PageToResultUtils.resultToPage(page), wrapper);
		if(iPage != null && iPage.getSize() > 0){
			for (Activity activity : iPage.getRecords()){
				if(!activity.getStatus().getCode().equals(ActivityStatus.STOP.getCode())){
					activity.setModifiedTime(null);
				}
			}
		}
		return iPage;
	}

	@Override
	public Activity getActivity(String id){
		ActivityEntity entity = getById(id);
		ActivitySpuRefQuery activitySpuRefQuery = new ActivitySpuRefQuery();
		activitySpuRefQuery.setActivityId(id);
		List<ActivitySpuRefEntity> list = activitySpuRefService.list(activitySpuRefQuery.toQueryWrapper());

		Activity activity = new Activity(entity);
		if(!CollectionUtils.isEmpty(list)) {
			activity.setList(list.stream().map(ActivitySpuRef::new).collect(Collectors.toList()));
		}
		return activity;
	}

	@Override
	public void saveLuckActivity(Activity activity){
		//数据校验
		checkData(activity);
		if(StringUtils.isEmpty(activity.getId())){
			//创建活动
			createActivity(activity);
		}else {
			//修改活动
			editActivity(activity);
		}
	}

	private void checkData(Activity activity){
		Check.notNull(activity.getBusdId(), BusinessCode.BUSDID_NOTNULL.getMessage());
		Check.notEmpty(activity.getActivityName(),"名称不能为空");
		Check.notEmpty(activity.getImg(),"图片不能为空");
		Check.notEmpty(activity.getDefaultMsg(),"默认提示不能为空");
		Check.notEmpty(activity.getFortunateMsg(),"中奖提示不能为空");
		Check.notEmpty(activity.getUnfortunateMsg(),"未中奖提示不能为空");
		Check.notEmpty(activity.getRepeatMsg(),"重复抽奖提示不能为空");
		Check.notNull(activity.getStartTime(),"有效期不能为空");
		Check.notNull(activity.getEndTime(),"有效期不能为空");
		Check.notNull(activity.getPersonTimesLimit(),"每人抽奖总次数不能为空");
		Check.positive(activity.getPersonTimesLimit(),"每人抽奖总次数必须是正数");
		Check.digits(activity.getPersonTimesLimit(), 10, 0, "每人抽奖总次数必须是正整数");
		Check.notNull(activity.getDayTimesLimit(),"每人每天抽奖次数不能为空");
		Check.positive(activity.getDayTimesLimit(),"每人每天抽奖次数必须是正数");
		Check.digits(activity.getDayTimesLimit(), 10, 0, "每人每天抽奖次数必须是正整数");
		Check.notNull(activity.getTriggerConditions(),"触发条件不能为空");
		Check.notEmpty(activity.getActivityRules(),"规则不能为空");
	}

	private void createActivity(Activity activity){
		//根据有效期与当前时间比较判断活动状态
		if(activity.getEndTime().isBefore(LocalDateTime.now())){
			//已过期
			throw new DragonException(MarketingCode.ACTIVITY_ENDTIME);
		}else if(activity.getStartTime().isAfter(LocalDateTime.now())){
			//待开始
			activity.setStatus(ActivityStatus.WAIT);
		}else{
			//进行中
			activity.setStatus(ActivityStatus.DOING);
		}
		if(activity.getTriggerConditions().contains("2")){
			Check.notNull(activity.getDays(),"累计签到天数不能为空");
		}
		save(activity);
		//新增活动奖品
		if(activity.getList() != null && activity.getList().size() > 0){
			for (ActivitySpuRef spuRef : activity.getList()){
				Check.notNull(spuRef.getSkuId(), "商品不能为空");
				SkuEntity sku = skuService.getById(spuRef.getSkuId());
				if(StringUtils.isEmpty(sku.getId())){
					throw new DragonException(MarketingCode.SPU_NOTNULL);
				}
				spuRef.setSkuId(sku.getId());
				spuRef.setActivityId(activity.getId());
				spuRef.setBusdId(activity.getBusdId());
				activitySpuRefService.save(spuRef);
			}
		}
	}

	private void editActivity(Activity activity){
		//修改活动
		baseMapper.updateById(activity);
		if(activity.getList() != null && activity.getList().size() > 0){
			ActivitySpuRefQuery spuRefQuery = new ActivitySpuRefQuery();
			spuRefQuery.setActivityId(activity.getId());
			activitySpuRefService.remove(spuRefQuery.toQueryWrapper());
			//修改活动奖品
			for (ActivitySpuRef spuRef : activity.getList()){
				//先删除之前的商品
				ActivitySpuRefQuery query = new ActivitySpuRefQuery();
				query.setActivityId(activity.getId());
				activitySpuRefService.remove(query.toQueryWrapper());
				//再添加商品
				Check.notNull(spuRef.getSkuId(), "商品不能为空");
				SkuEntity sku = skuService.getById(spuRef.getSkuId());
				if(StringUtils.isEmpty(sku.getId())){
					throw new DragonException(MarketingCode.SPU_NOTNULL);
				}
				spuRef.setSkuId(sku.getId());
				spuRef.setActivityId(activity.getId());
				spuRef.setBusdId(activity.getBusdId());
				activitySpuRefService.save(spuRef);
			}
		}
	}

	@Override
	public void stopActivity(String id){
		Check.notNull(id,"id不能为空");
		ActivityEntity activity = getById(id);
		if(activity.getStatus().getCode().equals(ActivityStatus.STOP.getCode())){
			throw new DragonException(MarketingCode.NORMAL_STOP);
		}
		activity.setStatus(ActivityStatus.STOP);
		baseMapper.updateById(activity);
	}

	@Override
	public void expireActivity(){
		//执行待开始到进行中
		expireReadyActivity();
		//执行进行中到过期
		expireNormalActivity();
	}

	private void expireReadyActivity(){
		ActivityQuery activityQuery = new ActivityQuery();
		activityQuery.setStatus(ActivityStatus.WAIT);
		List<ActivityEntity> list = list(activityQuery.toQueryWrapper());
		int proNum = 0;
		if(!list.isEmpty()){
			for (ActivityEntity activity : list){
				if(activity.getStartTime().isBefore(LocalDateTime.now()) && activity.getEndTime().isAfter(LocalDateTime.now())){
					activity.setStatus(ActivityStatus.DOING);
					baseMapper.updateById(activity);
				}
				if(activity.getEndTime().isBefore(LocalDateTime.now())){
					activity.setStatus(ActivityStatus.EXPIRED);
					baseMapper.updateById(activity);
				}
				proNum++;
			}
		}
		log.info("定时处理抽奖活动待开始到进行中,处理条数:" + proNum);
	}

	private void expireNormalActivity(){
		ActivityQuery activityQuery = new ActivityQuery();
		activityQuery.setStatus(ActivityStatus.DOING);
		List<ActivityEntity> list = list(activityQuery.toQueryWrapper());
		int proNum = 0;
		if(!list.isEmpty()){
			for (ActivityEntity activity : list){
				if(activity.getEndTime().isBefore(LocalDateTime.now())){
					activity.setStatus(ActivityStatus.EXPIRED);
					baseMapper.updateById(activity);
				}
				proNum++;
			}
		}
		log.info("定时处理抽奖活动进行中到过期,处理条数:" + proNum);
	}

}